package com.zhengshang.third.taobao;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.TypeUtils;
import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.*;
import com.taobao.api.response.*;
import com.zhengshang.api.domain.AppTaoRelation;
import com.zhengshang.api.service.IAppTaoRelationService;
import com.zhengshang.common.core.domain.AjaxResult;
import com.zhengshang.common.core.redis.RedisCache;
import com.zhengshang.common.utils.StringUtils;
import com.zhengshang.system.service.ISysConfigService;
import com.zhengshang.third.wikeyun.WikeyunApi;
import com.zhengshang.third.wikeyun.WikeyunUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 淘宝工具类
 */
@Component
public class TaoBaoUtils {

    /**
     * 授权Url
     * 拼接示例：https://oauth.taobao.com/authorize?response_type=code&client_id=11111111&redirect_uri=http://www.taobao.com&state=1212&view=web
     */
    private static final String oauthUrl = "https://oauth.taobao.com/authorize";
    /**
     * api请求地址
     */
    private static final String apiUrl = "https://eco.taobao.com/router/rest";

    /**
     * 淘宝应用appkey(等同于client_id)
     * 参考链接https://open.taobao.com/doc.htm?docId=118&docType=1
     * 参考链接https://open.taobao.com/doc.htm?docId=102635&docType=1#ss6
     */
    public static final String appKey = "32601467";
    /**
     * 淘宝应用密钥
     */
    public static final String appSecret = "f8cf26715fc67ed12630b219dac35fbc";

    /**
     * 推广位Id全部
     */
    public static final String pid = "mm_1736970083_2267850487_111284300164";

    /**
     * 推广位Id 只有最后一组
     */
    public static final Long adzoneId = 111284300164L;

    /**
     * 渠道/会员 推广位
     * https://mos.m.taobao.com/inviter/recruit?inviterCode=FDZEXX&src=pub&app=common
     */
    public static final String channelPid = "mm_1736970083_2296150409_112049900165";

    /**
     * 推广位Id 只有最后一组
     */
    public static final Long channelAdzoneId = 112049900165L;

    /**
     * 会员邀请码
     */
    public static final String inviterCode = "FDZEXX";
    /**
     * 饿了么活动Id
     */
    public static final String elmActivityMaterialId = "20150318019998877";

    /**
     *
     */
    public static final String weiKeYunTaobBaoRedisKey = "weiKeYunTaoBaoAccessToken";

    @Autowired
    private WikeyunUtils wikeyunUtils;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private IAppTaoRelationService appTaoRelationService;

    /**
     * 获取授权Url
     *
     * @param responseType (授权类型,值为code / token)
     * @param redirectUri  回调地址参数
     * @param view         (view参数可选值有：web、tmall、wap，其中：Web对应普通的PC端（淘宝logo）浏览器页面样式。Tmall对应天猫的浏览器页面样式。Wap对应无线端的浏览器页面样式。)
     * @return
     */
    private String getOauthUrl(String responseType, String redirectUri, String state, String view) {
        String text = oauthUrl + "?response_type=%s&client_id=%s&redirect_uri=%s&state=%s&view=%s";
        String content = String.format(text, responseType, appKey, redirectUri, state, view);
        return content;
    }

    /**
     * OauthUrl
     *
     * @param redirectUri
     * @return
     */
    public String getAppOauthUrl(String redirectUri, String state) {
        String oauthUrl = getOauthUrl("code", redirectUri, state, "wap");
        return oauthUrl;
    }

    /***
     * 获取授权微客云的accessToken
     * @return
     */
    public String getAccessTokenUrl() {
        String resultUrl = "http://i.itaoke.org/Oauth?do=taoyohui&view=%s";
        String domainUrl = sysConfigService.selectConfigByKey("sys.domain.name");
        String callbackUrl = domainUrl + "api/taobao/getWkYTaoBaoAccessToken";
        resultUrl = String.format(resultUrl, callbackUrl);
        return resultUrl;
    }

    /**
     * 根据code换取AccessToken
     * 6200b28a1d0ba8737eda6d6f2f71591de355ZZfa77e67112211072380717
     *
     * @param code
     * @return
     */
    public AjaxResult getAccessToken(String code) {
        try {
            TaobaoClient client = new DefaultTaobaoClient(apiUrl, appKey, appSecret);
            TopAuthTokenCreateRequest req = new TopAuthTokenCreateRequest();
            req.setCode(code);
            TopAuthTokenCreateResponse rsp = client.execute(req);
            String tokenResult = rsp.getTokenResult();
            JSONObject jsonObject = JSON.parseObject(tokenResult);
            String accessToken = jsonObject.getString("access_token");
            //accessToken 过期时间
            //授权有效期通过 expires_in 返回，请自行保存该数据，授权到期前，重新授权获取新的sessionkey，避免使用过期的sessionkey调用接口导致isv报错
            Integer expiresIn = jsonObject.getInteger("expires_in");
            //Refresh token，可用来刷新access_token
            //String refreshToken = jsonObject.getString("refresh_token");
            //String taobaoUserId = jsonObject.getString("taobao_user_id");
            return AjaxResult.success("获取成功", jsonObject);
        } catch (ApiException e) {
            e.printStackTrace();
            return AjaxResult.error(e.getErrMsg());
        }
    }

    /**
     * 刷新accessToken
     *
     * @param refreshToken
     */
    public AjaxResult refreshToken(String refreshToken) {
        try {
            TaobaoClient client = new DefaultTaobaoClient(apiUrl, appKey, appSecret);
            TopAuthTokenRefreshRequest req = new TopAuthTokenRefreshRequest();
            req.setRefreshToken(refreshToken);
            TopAuthTokenRefreshResponse rsp = client.execute(req);
            JSONObject jsonObject = JSON.parseObject(rsp.getTokenResult());
            return AjaxResult.success("获取成功", jsonObject);
        } catch (ApiException e) {
            e.printStackTrace();
            return AjaxResult.error(e.getErrMsg());
        }
    }

    /**
     * 淘宝客-推广者-物料搜索
     * 排序_des（降序），排序_asc（升序），销量（total_sales），淘客佣金比率（tk_rate）， 累计推广量（tk_total_sales），总支出佣金（tk_total_commi），价格（price），匹配分（match）
     *
     * @param pageNo
     */
    public AjaxResult materialOtionalSearch(String goodsName, Long pageNo, Boolean isTmall, String orderBy, String sort, Boolean hasCoupon) {
        List<TbkDgMaterialOptionalResponse.MapData> resultList = Lists.newArrayList();
        TaobaoClient client = new DefaultTaobaoClient(apiUrl, appKey, appSecret);
        TbkDgMaterialOptionalRequest req = new TbkDgMaterialOptionalRequest();
        req.setPageSize(10L);
        req.setPageNo(pageNo);
        //链接形式：1：PC，2：无线，默认：１
        req.setPlatform(2L);
        req.setIsOverseas(false);
        //商品筛选-是否天猫商品。true表示属于天猫商品，false或不设置表示不限
        req.setIsTmall(isTmall);
        req.setSort(orderBy + "_" + sort);
        req.setQ(goodsName);
        if (StringUtils.isNotNull(hasCoupon)) {
            req.setHasCoupon(hasCoupon);
        }
        req.setAdzoneId(adzoneId);
        try {
            TbkDgMaterialOptionalResponse rsp = client.execute(req);
            resultList = rsp.getResultList();
            return AjaxResult.success(resultList);
        } catch (ApiException e) {
            e.printStackTrace();
            return AjaxResult.error(e.getErrMsg());
        }
    }


    /**
     * 查询订单
     *
     * @param queryType     查询时间类型，1：按照订单淘客创建时间查询，2:按照订单淘客付款时间查询，3:按照订单淘客结算时间查询，4:按照订单更新时间；
     * @param positionIndex 位点，除第一页之外，都需要传递；前端原样返回。
     * @param pageNo        第几页，默认1，1~100
     * @param pageSize      页大小，默认20，1~100
     * @param memberType    推广者角色类型,2:二方，3:三方，不传，表示所有角色
     * @param tkStatus      淘客订单状态，12-付款，13-关闭，14-确认收货，3-结算成功;不传，表示所有状态
     * @param endTime       订单查询结束时间，订单开始时间至订单结束时间，中间时间段日常要求不超过3个小时，但如618、双11、年货节等大促期间预估时间段不可超过20分钟，超过会提示错误，调用时请务必注意时间段的选择，以保证亲能正常调用！
     * @param startTime     订单查询开始时间
     * @param jumpType      跳转类型，当向前或者向后翻页必须提供,-1: 向前翻页,1：向后翻页
     * @param orderScene    场景订单场景类型，1:常规订单，2:渠道订单，3:会员运营订单，默认为1
     */
    public AjaxResult queryOrderList(Integer queryType, String positionIndex, Integer pageNo, Integer pageSize, Integer memberType, String tkStatus, String endTime, String startTime, Integer jumpType, Integer orderScene) {
        boolean haveKey = redisCache.hasKey(weiKeYunTaobBaoRedisKey);
        //没有淘宝token直接返回
        if (!haveKey) {
            return AjaxResult.error("淘宝账户授权给微客云weiKeYunTaoBaoAccessToken已过期");
        }
        Map<String, Object> map = redisCache.getCacheObject(weiKeYunTaobBaoRedisKey);
        String accessToken = (String) map.get("token");
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("queryType", queryType);
        params.put("position_index", positionIndex);
        params.put("page_no", pageNo);
        params.put("page_size", pageSize);
        if (StringUtils.isNotNull(memberType)) {
            params.put("member_type", memberType);
        }
        if (StringUtils.isNotEmpty(tkStatus)) {
            params.put("tk_status", tkStatus);
        }
        params.put("end_time", endTime);
        params.put("start_time", startTime);
        params.put("jump_type", jumpType);
        params.put("order_scene", orderScene);
        params.put("access_token", accessToken);
        String result = wikeyunUtils.sendPostRequest(params, WikeyunApi.taobaoOrderList);
        JSONObject jsonObject = JSONObject.parseObject(result);
        return wikeyunUtils.converAjaxResult(jsonObject);
    }

    /**
     * 私域用户备案(主要处理淘宝和用户的关系)
     *
     * @param userId       系统内部userId
     * @param relationFrom 渠道备案 - 来源，取链接的来源 不必填
     * @param note         媒体侧渠道备注
     */
    public AjaxResult savePublisher(Long userId, String taoBaoAccessToken, String relationFrom, String note) {
        try {
            //没有淘宝token直接返回
            if (StringUtils.isEmpty(taoBaoAccessToken)) {
                return AjaxResult.error("缺少淘宝token");
            }
            TaobaoClient client = new DefaultTaobaoClient(apiUrl, appKey, appSecret);
            TbkScPublisherInfoSaveRequest req = new TbkScPublisherInfoSaveRequest();
            req.setRelationFrom(relationFrom);
            req.setOfflineScene("4");
            req.setOnlineScene("3");
            req.setInviterCode(inviterCode);
            req.setInfoType(1L);
            req.setNote(note);
            TbkScPublisherInfoSaveResponse rsp = client.execute(req, taoBaoAccessToken);
            String errorCode = rsp.getErrorCode();
            if (StringUtils.isNotEmpty(errorCode)) {
                return AjaxResult.error(rsp.getSubMsg());
            }
            TbkScPublisherInfoSaveResponse.Data data = rsp.getData();
            Long relationId = data.getRelationId();
            Long specialId = data.getSpecialId();
            String accountName = data.getAccountName();
            int num = appTaoRelationService.countNumByUserId(userId);
            if (num <= 0) {
                AppTaoRelation appTaoRelation = new AppTaoRelation();
                appTaoRelation.setUserId(userId);
                appTaoRelation.setRelationId(relationId);
                appTaoRelation.setSpecialId(specialId);
                appTaoRelation.setAccountName(accountName);
                appTaoRelation.setAccessToken(taoBaoAccessToken);
                appTaoRelationService.insertAppTaoRelation(appTaoRelation);
            } else {
                AppTaoRelation appTaoRelation = appTaoRelationService.findByUserId(userId);
                appTaoRelation.setAccessToken(taoBaoAccessToken);
                appTaoRelationService.updateAppTaoRelation(appTaoRelation);
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return AjaxResult.success("系统用户与淘宝私域已进行关联",new HashMap<>());
    }

    /**
     * 淘宝客-推广者-官方活动转链 )
     * 支持入参推广位和官方活动会场ID，获取活动信息和推广链接，包含推广长链接、短链接、淘口令、微信推广二维码地址等。改该API支持二方、三方类型的转链。官方活动会场ID，从淘宝客后台“我要推广-活动推广”中获取。
     */
    public AjaxResult getActivityInfo(String activityMaterialId, Long userId) {
        try {
            TaobaoClient client = new DefaultTaobaoClient(apiUrl, appKey, appSecret);
            TbkActivityInfoGetRequest req = new TbkActivityInfoGetRequest();
            req.setActivityMaterialId(activityMaterialId);
            req.setAdzoneId(adzoneId);
            req.setSubPid(pid);
            req.setUnionId(String.valueOf(userId));
            TbkActivityInfoGetResponse rsp = client.execute(req);
            String errorCode = rsp.getErrorCode();
            if (StringUtils.isNotEmpty(errorCode)) {
                return AjaxResult.error(rsp.getSubMsg());
            }
            TbkActivityInfoGetResponse.Data data = rsp.getData();
            return AjaxResult.success(data);
        } catch (ApiException e) {
            e.printStackTrace();
            return AjaxResult.error(e.getErrMsg());
        }
    }

    /**
     * 支持入参对应的“推广位”和官方提供的“物料id”，获取指定物料信息和推广链接，还可入参用户信息提供智能推荐
     * （需智能推荐请先前协议https://pub.alimama.com/fourth/protocol/common.htm?key=hangye_laxin）
     */
    public AjaxResult optimusMaterial(Long activityMaterialId) {
        try {
            TaobaoClient client = new DefaultTaobaoClient(apiUrl, appKey, appSecret);
            TbkDgOptimusMaterialRequest req = new TbkDgOptimusMaterialRequest();
            req.setPageSize(6L);
            req.setPageNo(1L);
            req.setAdzoneId(adzoneId);
            req.setMaterialId(activityMaterialId);
            TbkDgOptimusMaterialResponse rsp = client.execute(req);
            String errorCode = rsp.getErrorCode();
            if (StringUtils.isNotEmpty(errorCode)) {
                return AjaxResult.error(rsp.getSubMsg());
            }
            List<TbkDgOptimusMaterialResponse.MapData> resultList = rsp.getResultList();
            return AjaxResult.success(resultList);
        } catch (ApiException e) {
            e.printStackTrace();
            return AjaxResult.error(e.getErrMsg());
        }
    }
}
